<?php
namespace App\Services\Integral\Integral;

use App\Models\IntegralOrder\Account;
use App\Models\IntegralOrder\OptionLog;
use App\Models\IntegralOrder\Order;
use App\Models\Goods\Goods;
use App\Models\User\User;
use App\Models\MyAddr\MyAddr;
use App\Services\Setting\SettingIndex;
use App\Services\User\Traits\Password;
use DB;
use App\Services\Log\Log\LogLogic;
/**
 * @Author: 于婧雯
 * @Date:   2019-03-01 16:25:06
 * @Last Modified by:   ws
 * @Last Modified time: 2019-03-01
 */
class IntegralLogic
{
    use Password;
    /*积分操作（增加）（接单成功奖励等）*/
    public function addIntegral($data): array
    {

        DB::beginTransaction();
        try {
            //加积分
            $integralSetting = SettingIndex::SettingCategory()->getSelection(['action' => 'integralSetting']);
            $signInt = $integralSetting['take_order'][0];
            $integralMod = Account::where(['user_id' => $data['user_id']])->first();
            $integralMod->total = $integralMod->total + $signInt;
            $integralMod->income = $integralMod->income + $signInt;
            $integralMod->available_integral = $integralMod->available_integral + $signInt;
            $r1 = $integralMod->save();

            //添加积分操作日志
            $logData = [
                'user_id' => $data['user_id'],
                'type' => 'add',
                'integral' => $signInt,
                'total' => $integralMod->total,
                'income' => $integralMod->income,
                'available_integral' => $integralMod->available_integral,
                'expend' => $integralMod->expend,
                'freeze' => $integralMod->freeze,
                'remark' => $data['remark'].$signInt.'积分',
                'create_time' => NOW,
                'update_time' => NOW,
            ];
            $r2 = OptionLog::insert($logData);

            if ($r1 && $r2) {
                DB::commit();
                return auto_success(null, '增加积分成功');
            }else{
                DB::rollBack();
                return auto_failure(null, '增加积分失败');
            }
        } catch (\Exception $e) {
            DB::rollBack();
            return auto_failure($e->getMessage(), '增加积分失败');
        }
    }

    /*用户积分详情*/
    public function integralInfo($data): array
    {
        $_where['user_id'] = $data['user_id'];
        $_where['status'] = 1;
        $res = Account::where($_where)->select()->first();
        return auto_return($res);
    }

    /*用户积分记录*/
    public function integralList($data): array
    {
        $_where['user_id'] = $data['user_id'];
        $_where['status'] = 1;
        $res = OptionLog::where($_where)->paginate(10);
        return auto_return($res);
    }

    /*兑换记录列表*/
    public function orderList($data): array
    {
        $_where['user_id'] = $data['user_id'];
        $_where['is_del'] = 0;
        $res = Order::with('goods')->where($_where)->orderBy('id','desc')->paginate(10);
        return auto_return($res);

    }

    /*用户积分列表 可查用户*/
    public function adminIntegralList($data): array
    {
        $_where['status'] = 1;
        $re = Account::where($_where);
        if($data['keywords']){
            $re->where(function($query) use ($data){
                $query->where('user_id', '=', $data['keywords']);});
        }
        $res = $re->paginate(10);
        return auto_return($res);
    }

    /*积分操作记录 可查用户*/
    public function adminOptionLog($data): array
    {
        $_where['status'] = 1;
        $re = OptionLog::where($_where);
        if($data['keywords']){
            $re->where(function($query) use ($data){
                $query->where('user_id', '=', $data['keywords']);
            });
        }
        $res = $re->orderBy('id','desc')->paginate(10);
        return auto_return($res);

    }

    /*用户兑换记录列表 可查用户*/
    public function adminOrderList($data): array
    {
        $_where['integral_order.is_del'] = 0;
        $re = Order::join('goods', 'integral_order.goods_id', '=', 'goods.id')
            ->select('goods.title','integral_order.*')->where($_where);
        if($data['keywords']){
            $keyword = $data['keywords'];
            $re->where(function($query) use ($keyword){
                $query->where('integral_order.user_id', '=', $keyword)->orWhere('integral_order.order_code','like',"%".$keyword."%")->orWhere('goods.title','like',"%".$keyword."%");
            });
        }
        $res = $re->orderBy('id','desc')->paginate(10);
        return auto_return($res);
    }

    /*发货*/
    public function deliverGoods($data): array
    {
        DB::beginTransaction();
        try {
            //查看订单信息
            $order = Order::where(['id' => $data['id']])->first();
            //扣除积分并写入日志
            $res = $this->deductIntegral($order->user_id, $order->integral);
            if ($res['status'] !== SUCCESS_STATUS) {
                DB::rollBack();
                new \Exception('扣除积分失败');
            }
            //修改订单信息
            $order->transfer_status = 1;
            $order->freeze_status = 0;
            $order->shipments_time = time();
            $order->update_time = time();
            $order->save();
            DB::commit();
            return auto_success(null,'兑换成功');
        } catch (\Exception $e) {
            DB::rollBack();
            return auto_failure($e->getMessage(), '兑换失败');
        }

    }

    /*生成订单*/
    public function addOrder($data)
    {
        //验证用户支付密码
        $info = User::select('pay_password','pay_salt')
            ->where(['id' => $data['user_id']])
            ->first()
            ->toArray();
        if(!$info){
            return verify_err(null, '没有相关用户信息');
        }else if($info['pay_password'] === ''){
            return verify_err(null, '您还没有设置支付密码');
        }
        // 验证支付密码
        $check = $this->_checkPayPassword($data['pay_password'], $info);
        if(!$check){
            return verify_err(null, '支付密码错误');
        }
        //查找用户收货地址
        $addr = MyAddr::select()
            ->where(['id' => $data['addr_id']])
            ->first()
            ->toArray();
        //计算商品价格
        $_where['id'] = $data['goods_id'];
        $_where['is_del'] = 0;
        $re = Goods::where($_where)->select()->first();
        $price = $re->price * $data['number'];
        $newData = [
            'user_id' => $data['user_id'],
            'goods_id' => $data['goods_id'],
            'number' => $data['number'],
            'remark' => $data['remark'],
            'order_code' => $this->createOrderNum(),
            'integral' => $price,
            'name' => $data['name'],
            'phone' => $data['phone'],
            'addr' => $addr['province'].$addr['city'].$addr['county'].$addr['addr'],
            'freeze_status' => 1,
            'transfer_status' => 0,
            'pay_time' => time(),
            'create_time' => time(),
            'update_time' => time()
        ];
        DB::beginTransaction();
        try {
            //冻结积分并写入日志
            $res = $this->freezeIntegral($data['user_id'], $newData['integral']);
            if ($res['status'] !== SUCCESS_STATUS) {
                DB::rollBack();
                new \Exception('冻结积分失败');
            }
            //生成订单
            Order::insert($newData);
            //商品表商品数量-1
            $result = Goods::where(['id' => $data['goods_id']])->first();
            $newRemain = bcsub($result->remain, $data['number'],2);
            $result->remain = $newRemain;
            $result->save();
            DB::commit();
            return auto_success(null,'兑换成功');
        } catch (\Exception $e) {
            DB::rollBack();
            return auto_failure($e->getMessage(), '兑换失败');
        }
    }
    /**
     * 冻结积分并且写入积分操作日志
     * @param $userId
     * @param $num
     * @param string $remark
     * @return array
     */
    private function freezeIntegral($userId, $num)
    {
        $account = Account::where(['user_id' => $userId])->first();
        $bccompRes = bccomp($account->available_integral, $num);
        if (!$bccompRes)
            new \Exception('积分不足');
        $newAvailable = bcsub($account->available_integral, $num,2);
        $newTotal = bcsub($account->total, $num,2);
        $newFreeze = bcadd($account->freeze, $num,2);
        $account->available_integral = $newAvailable;
        $account->total = $newTotal;
        $account->freeze = $newFreeze;

        $logData = [
            'user_id' => $userId,
            'type' => 'freeze',
            'integral' => $num,
            'total' => $newTotal,
            'income' => $account->income,
            'expend' => $account->expend,
            'available_integral' => $newAvailable,
            'freeze' => $account->freeze,
            'remark' => '兑换商品成功'.'冻结'.$num.'积分',
            'create_time' => NOW,
            'update_time' => NOW
        ];

        try {
            OptionLog::insert($logData);
            $res = $account->save();
            return auto_success($res);
        } catch (\Exception $e) {
            return auto_failure($e->getMessage(), '冻结积分失败');
        }
    }
    /**
     * 扣除冻结积分并且写入积分操作日志
     * @param $userId
     * @param $num
     * @param string $remark
     * @return array
     */
    private function deductIntegral($userId, $num)
    {
        $account = Account::where(['user_id' => $userId])->first();
        $bccompRes = bccomp($account->freeze, $num);
        if (!$bccompRes)
            new \Exception('积分不足');
        $newFreeze = bcsub($account->freeze, $num,2);
        $newExpend = bcadd($account->expend, $num,2);
        $account->freeze = $newFreeze;
        $account->expend = $newExpend;

        $logData = [
            'user_id' => $userId,
            'type' => 'freeze',
            'integral' => $num,
            'total' => $account->total,
            'income' => $account->income,
            'expend' => $newExpend,
            'available_integral' => $account->available_integral,
            'freeze' => $newFreeze,
            'remark' => '发货成功'.'扣除'.$num.'积分',
            'create_time' => NOW,
            'update_time' => NOW
        ];

        try {
            OptionLog::insert($logData);
            $res = $account->save();
            return auto_success($res);
        } catch (\Exception $e) {
            return auto_failure($e->getMessage(), '扣除积分失败');
        }
    }

    private function createOrderNum()
    {
        $num = date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
        return $num;
    }


}
